home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
399_01
/
minedio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-03
|
28KB
|
1,329 lines
/* ================================================================== *
* Editor mined *
* Operating system dependant I/O *
* ================================================================== */
#include "mined.h"
#include <errno.h>
#include <signal.h>
#ifdef CURSES
#include <curses.h>
#undef FALSE
#undef TRUE
#undef TERMIO /* \ must be */
#undef SGTTY /* / disabled */
#endif
#ifdef TERMIO
#include <termios.h>
#endif
#ifdef SGTTY
#include <sys/ioctl.h> /* <sgtty.h> ? */
extern void ioctl ();
#endif
#ifdef SIGPHONE /* this trick was taken from less' screen.c */
#include <sys/window.h> /* for window size detection */
#endif
#ifdef msdos
#define _getch_
#include <dos.h>
#endif
#ifdef unix
#include <sys/time.h> /* for struct timeval (for select in inputreadyafter) */
#define selectread /* use select () ? */
#endif
#ifdef vms
#include <socket.h> /* for select () and struct timeval */
# ifdef CURSES
# define _getch_
# endif
#endif
#ifdef _getch_
#ifndef CURSES
extern int getch ();
#endif
#endif
/* ================================================================== *
* Unix signalling routines *
* ================================================================== */
void
catch_signals (catch)
void (* catch) ();
{
#ifdef SIGHUP
signal (SIGHUP, catch);
#endif
#ifdef SIGILL
signal (SIGILL, catch);
#endif
#ifdef SIGTRAP
signal (SIGTRAP, catch);
#endif
#ifdef SIGABRT
signal (SIGABRT, catch);
#endif
#ifdef SIGEMT
signal (SIGEMT, catch);
#endif
#ifdef SIGFPE
signal (SIGFPE, catch);
#endif
#ifdef SIGBUS
signal (SIGBUS, catch);
#endif
#ifdef SIGSEGV
signal (SIGSEGV, catch);
#endif
#ifdef SIGSYS
signal (SIGSYS, catch);
#endif
#ifdef SIGPIPE
signal (SIGPIPE, catch);
#endif
#ifdef SIGALRM
signal (SIGALRM, catch);
#endif
#ifdef SIGTERM
signal (SIGTERM, catch);
#endif
#ifdef SIGXCPU
signal (SIGXCPU, catch);
#endif
#ifdef SIGXFSZ
signal (SIGXFSZ, catch);
#endif
#ifdef SIGVTALRM
signal (SIGVTALRM, catch);
#endif
#ifdef SIGPROF
signal (SIGPROF, catch);
#endif
#ifdef SIGLOST
signal (SIGLOST, catch);
#endif
#ifdef SIGUSR1
signal (SIGUSR1, catch);
#endif
#ifdef SIGUSR2
signal (SIGUSR2, catch);
#endif
#ifdef SIGUSR3
signal (SIGUSR3, catch);
#endif
}
#ifdef SIGTSTP
void
suspendmyself ()
{
kill (getpid (), SIGTSTP);
}
FLAG cansuspendmyself = TRUE;
#else
void
suspendmyself ()
{}
FLAG cansuspendmyself = FALSE;
#endif
#ifdef SIGWINCH
/*
* Catch the SIGWINCH signal sent to mined.
*/
void
catchwinch ()
{
winchg = TRUE;
/* if (waitingforinput == TRUE) RDwin (); */
/* This is now performed in __readchar () to prevent display garbage
in case this interrupts occurs during display output operations which
get screen size related values changed while relying on them. */
signal (SIGWINCH, catchwinch); /* Re-installation of the signal */
}
#endif
#ifdef SIGQUIT
/*
* Catch the SIGQUIT signal (^\) sent to mined. It turns on the quitflag.
*/
void
catchquit ()
{
#ifdef UNUSED /* Should not be needed with new __readchar () */
/* Was previously needed on SUN but showed bad effects on Iris. */
static char quitchar = '\0';
if (waitingforinput == TRUE)
/* simulate input to enable immediate break also during input */
ioctl (input_fd, TIOCSTI, & quitchar);
#endif
quit = TRUE;
signal (SIGQUIT, catchquit); /* Re-installation of the signal */
}
#endif
#ifdef SIGBREAK
/*
* Catch the SIGBREAK signal (control-Break) and turn on the quitflag.
*/
void
catchbreak ()
{
quit = TRUE;
signal (SIGBREAK, catchbreak); /* do we need this ? */
}
#else
# ifdef msdos
int
controlbreak ()
{
quit = TRUE;
return 1 /* continue program execution */;
}
# endif
#endif
#ifdef SIGINT
/*
* Catch the SIGINT signal (^C) sent if it cannot be ignored by tty driver
*/
void
catchint ()
{
intr_char = TRUE;
signal (SIGINT, catchint); /* Re-installation of the signal */
}
#endif
/* ================================================================== *
* Terminal mode switcher *
* ================================================================== */
/*
* Set and reset tty into CBREAK or old mode according to argument `state'.
* It also sets all signal characters (except for ^\) to UNDEF. ^\ is caught.
*/
void
raw_mode (state)
FLAG state;
{
#ifdef TERMIO
static struct termios old_termio;
struct termios new_termio;
#ifdef TCGETS
# define gettermio(fd, iopoi) ioctl (fd, TCGETS, iopoi);
# ifdef TCSETSW
# define settermio(fd, iopoi) ioctl (fd, TCSETSW, iopoi);
# else
# define settermio(fd, iopoi) ioctl (fd, TCSETS, iopoi);
# endif
#else
# define gettermio(fd, iopoi) tcgetattr (fd, iopoi);
# ifdef TCSADRAIN
# define settermio(fd, iopoi) tcsetattr (fd, TCSADRAIN, iopoi);
# else
# define settermio(fd, iopoi) tcsetattr (fd, 0, iopoi);
# endif
#endif
#endif /* TERMIO */
#ifdef SGTTY
static struct sgttyb old_tty;
struct sgttyb new_tty;
static int oldlmode;
int lmode;
static struct tchars old_tchars;
static struct ltchars old_ltchars;
#define NDEF '\377'
static struct tchars new_tchars = {NDEF, QUITCHAR, NDEF, NDEF, NDEF, NDEF};
static struct tchars new_QStchars = {NDEF, QUITCHAR, '\021', '\023', NDEF, NDEF};
static struct ltchars new_ltchars = {NDEF, NDEF, NDEF, NDEF, NDEF, NDEF};
/* correspondence between the tchars/ltchars characters of the sgtty
interface and the c_cc characters of the termios interface (codes vary):
sgtty termio sgtty termio
t_intrc VINTR t_suspc VSUSP
t_quitc VQUIT t_dsuspc VDSUSP
t_startc VSTART t_rprntc VREPRINT
t_stopc VSTOP t_flushc VDISCARD
t_eofc VEOF (VMIN) t_werasc VWERASE
t_brkc VEOL (VTIME) t_lnextc VLNEXT
*/
#endif /* SGTTY */
if (state == OFF) {
isscreenmode = FALSE;
#ifdef CURSES
endwin ();
#ifdef vms
system ("set terminal /ttsync /nopasthru");
#endif
#else /* ndef CURSES: */
end_screen_mode ();
flush ();
#endif /* ndef CURSES */
#ifdef TERMIO
settermio (input_fd, & old_termio);
#endif
#ifdef SGTTY
ioctl (input_fd, TIOCSETP, & old_tty);
ioctl (input_fd, TIOCSETC, & old_tchars);
ioctl (input_fd, TIOCSLTC, & old_ltchars);
ioctl (input_fd, TIOCLSET, & oldlmode);
#endif
return;
}
else /* (state == ON) */ {
isscreenmode = TRUE;
#ifdef CURSES
refresh ();
#else
start_screen_mode ();
flush ();
#endif
#ifdef TERMIO
gettermio (input_fd, & old_termio);
gettermio (input_fd, & new_termio);
if (controlQS == FALSE)
new_termio.c_iflag &= ~(ISTRIP|IXON|IXOFF);
else
new_termio.c_iflag &= ~(ISTRIP);
new_termio.c_oflag &= ~OPOST;
new_termio.c_cflag &= ~(PARENB|CSIZE);
new_termio.c_cflag |= CS8;
new_termio.c_lflag &= ~(ICANON|ECHO);
#define NDEF '\000'
new_termio.c_cc [VMIN] = 1;
new_termio.c_cc [VTIME] = 0;
new_termio.c_cc [VQUIT] = QUITCHAR;
new_termio.c_cc [VINTR] = NDEF;
new_termio.c_cc [VSUSP] = NDEF;
#ifdef VDISCARD
new_termio.c_cc [VDISCARD] = NDEF;
#endif
settermio (input_fd, & new_termio);
#endif /* TERMIO */
#ifdef SGTTY
/* Save old tty settings */
ioctl (input_fd, TIOCGETP, & old_tty);
ioctl (input_fd, TIOCGETC, & old_tchars);
ioctl (input_fd, TIOCGLTC, & old_ltchars);
ioctl (input_fd, TIOCLGET, & oldlmode);
/* Set line mode */
/* If this feature should not be available on some system, RAW must be used
instead of CBREAK below to enable 8 bit characters on output */
lmode = oldlmode;
lmode |= LPASS8; /* enable 8 bit characters on input in CBREAK mode */
lmode |= LLITOUT; /* enable 8 bit characters on output in CBREAK mode;
this may not be necessary in newer Unixes, e.g. SUN-OS 4;
output handling is slightly complicated by LITOUT */
ioctl (input_fd, TIOCLSET, & lmode);
/* Set tty to CBREAK (or RAW) mode */
new_tty = old_tty;
new_tty.sg_flags &= ~ECHO;
new_tty.sg_flags |= CBREAK;
ioctl (input_fd, TIOCSETP, & new_tty);
/* Unset signal chars */
if (controlQS == FALSE)
ioctl (input_fd, TIOCSETC, & new_tchars); /* Only leaves QUITCHAR */
else
ioctl (input_fd, TIOCSETC, & new_QStchars); /* Leaves QUITCHAR, ^Q, ^S */
ioctl (input_fd, TIOCSLTC, & new_ltchars); /* Leaves nothing */
#endif /* SGTTY */
/* Define signal handlers */
#ifdef SIGQUIT
signal (SIGQUIT, catchquit); /* Catch QUITCHAR (^\) */
#endif
#ifdef SIGBREAK
signal (SIGBREAK, catchbreak); /* contro